<?php
use Monolog\Logger;
use Illuminate\Support\Facades\Redis;
use Monolog\Handler\StreamHandler;
use AlibabaCloud\Client\AlibabaCloud;
use AlibabaCloud\Client\Exception\ClientException;
use AlibabaCloud\Client\Exception\ServerException;

function randomkeys($length=32)   
{   
	// ,./\\|~!@#$%^&*();:\'\"
   $pattern = '1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLOMNOPQRSTUVWXYZ';  
    $len_ = strlen( $pattern)-1;
    $key = '';
    for($i=0;$i<$length;$i++)   
    {   
        mt_srand();
        $key .= $pattern{mt_rand(0,$len_)};    //生成php随机数   
    }   
    return $key;   
} 

if(!function_exists('nonce_str')) {
    /**
     * @param int $params
     * @return string
     */
    function nonce_str($param)
    {
        $str="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        $key = "";
        for($i=0;$i<$param;$i++)
        {
            mt_srand();
            $key .= $str{mt_rand(0,32)};    //生成php随机数
        }
        return $key;
    }
}

function get_client_ip()
{
    if (getenv("HTTP_CLIENT_IP") && strcasecmp(getenv("HTTP_CLIENT_IP"), "unknown"))
        $ip = getenv("HTTP_CLIENT_IP");
    else if (getenv("HTTP_X_FORWARDED_FOR") && strcasecmp(getenv("HTTP_X_FORWARDED_FOR"), "unknown"))
        $ip = getenv("HTTP_X_FORWARDED_FOR");
    else if (getenv("REMOTE_ADDR") && strcasecmp(getenv("REMOTE_ADDR"), "unknown"))
        $ip = getenv("REMOTE_ADDR");
    else if (isset($_SERVER ['REMOTE_ADDR']) && $_SERVER ['REMOTE_ADDR'] && strcasecmp($_SERVER ['REMOTE_ADDR'], "unknown"))
        $ip = $_SERVER ['REMOTE_ADDR'];
    else
        $ip = "unknown";
    if(!filter_var($ip, FILTER_VALIDATE_IP)){
        return '';
    }
    return $ip;
} 

function create_order_id() {
    $year_code = array('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K');
    return $year_code[intval(date('Y')) - 2017] .
            strtoupper(dechex(date('m'))) . date('d') . substr(time(), -5) . substr(microtime(), 2, 5) . sprintf('%03d', mt_rand(0, 500));
}

if(!function_exists('array_getstr')) {
    /**
     * @param array $data
     * @param string $sign
     * @return bool
     */
    function array_getstr($data) {
        $str = '';

        foreach ($data as $key=> $value){
            if(!empty($str)) $str .="&";
            $str .= $key."=".$value;
        }

        return $str;
    }
}

if(!function_exists('curl_get_common')) {
    /**
     * 通常curl请求，返回请求值
     * @param unknown $url
     * @return boolean
     */
    function curl_get_common($url) {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);    // 要求结果为字符串且输出到屏幕上
        curl_setopt($ch, CURLOPT_HEADER, 0); // 不要http header 加快效率
        curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (compatible; MSIE 5.01; Windows NT 5.0)');
        curl_setopt($ch, CURLOPT_TIMEOUT, 5);
        $output = curl_exec($ch);
        $output = json_decode($output);
        curl_close($ch);

        return $output;
    }
}


if(!function_exists('arr_xml')) {
    /**
     * 数组转XML
     * @param int $params
     * @return string
     */
    function arr_xml($arr)
    {
        $xml = "<xml>";
        foreach ($arr as $key=>$val)
        {
            if (is_numeric($val)){
                $xml.="<".$key.">".$val."</".$key.">";
            }else{
                $xml.="<".$key."><![CDATA[".$val."]]></".$key.">";
            }
        }
        $xml.="</xml>";
        return $xml;
    }
}

if(!function_exists('curl_post_common')) {
    /**
     * 通常curl请求，返回请求值
     * @param unknown $url
     * @param unknown $post_data
     * @return boolean
     */
    function curl_post_common($url,$post_data='')
    {
        /*
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_TIMEOUT, 20);
        curl_setopt($ch, CURLOPT_POSTFIELDS,  $post_data);
        $output = curl_exec($ch);
        //$output = json_decode($output);
        curl_close($ch);
        return $output;
        */       
        
        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
        curl_setopt($ch, CURLOPT_TIMEOUT, 20);
        $response = curl_exec($ch);
        $errno    = curl_errno($ch);
        curl_close($ch);
        if ($errno != 0)
        {   
            //curl请求有错误
            return false;
        }
        else
        {
            return $response;
        }
        
    }
}

//写错误日志
function writeLog(string $level, string $prefix, string $msg){
    $log = new Logger($prefix);
    $file = base_path("storage") . "/logs/".$prefix."_LOG-" . date("Y-m-d") . ".log";
    switch($level){
        case 'error':
        {
            $log->pushHandler(new StreamHandler($file, Logger::ERROR)); 
            $log->err($msg);
        }
        break;
        case 'debug':
        {
            $log->pushHandler(new StreamHandler($file, Logger::DEBUG)); 
            $log->debug($msg);
        }
        break;
        case 'info':
        {
            $log->pushHandler(new StreamHandler($file, Logger::INFO)); 
            $log->info($msg);
        }
        break;
        default:
            break;
    }
}

//判断某个字符串是否包含指定的子字符串
function sensitiveWordFilter($str){
    // 最高级别过滤
    // if ($str) {
    //     return '根据最高个人想法，禁止发言';
    // }
    //$words = getSensitiveWords();
    $words = [];
    $arr = file(base_path().'/resources/shieldword/ShieldWordCfg');
    foreach($arr as $line => $content){
        $tmpStr = trim($content, $character_mask=" \t\n\r\0\x0B,\"");
        if($tmpStr != ""){
            $words[] = $tmpStr;
        }
    }
        // 建议从文件或者缓存中读取敏感词列表，英文约定小写
    $flag = true;
    // 提取中文部分，防止其中夹杂英语等
    preg_match_all("/[\x{4e00}-\x{9fa5}]+/u", $str, $match);
    $chineseStr = implode('', $match[0]);
    $englishStr = strtolower(preg_replace("/[^A-Za-z0-9\.\-]/", " ", $str));
    $flag_arr = array('？', '！', '￥', '（', '）', '：' , '‘' , '’', '“', '”', '《' , '》', '，', 
    '…', '。', '、', 'nbsp', '】', '【' ,'～', '#', '$', '^', '%', '@', '!', '*', '-'. '_', '+', '=');
    $contentFilter = preg_replace('/\s/', '', preg_replace("/[[:punct:]]/", '', 
    strip_tags(html_entity_decode(str_replace($flag_arr, '', $str), ENT_QUOTES, 'UTF-8'))));
    // 全匹配过滤,去除特殊字符后过滤中文及提取中文部分
    foreach ($words as $word)
    {
        // 判断是否包含敏感词,可以减少这里的判断来降低过滤级别，
        if (strpos($str, $word) !== false || strpos($contentFilter, $word) !== false || strpos($chineseStr, $word) !== false 
        || strpos($englishStr, $word) !== false) {
            return '敏感词:' . $word;
        }
    }
    return $flag;
}

//屏蔽文本中的a标签
function filterATag($str){
    return preg_replace('/<[aA][\s\n]+[\s\S]*?>|<\/[aA][\s\S]*?>/','',$str);
}


/**
 * 数据转化为字符串
 * 目前仅支持数组
 */
function dataToString($datas)
{
    switch (gettype($datas))
    {
        case "boolean":
            $datas = $datas ? "1" : "0";
            break;
        case "integer":
            $datas = (string)$datas;
            break;
        case "double":
            $datas = (string)$datas;
            break;
        case "string":
            break;
        case 'array':
            array_walk($datas, function(&$data){
                if(is_array($data))
                {
                    dataToString($data);
                }
                else
                {
                    $data = (string)$data;
                }
            });
            break;
        case 'resource':
            break;
        case "NULL":
            $datas = "";
            break;
        default:
    }
    return $datas;
}

/**
 * 打印执行的sql，与endGetExcuteSql() 同时使用，在执行完sql方法之前调用
 */
function startGetExcuteSql()
{
    \Illuminate\Support\Facades\DB::connection()->enableQueryLog();
}

/**
 * 打印执行的sql，startGetExcuteSql() 同时使用，在执行完sql方法之后调用
 */
function endGetExcuteSql()
{
    echo '<pre>';
    print_r(\Illuminate\Support\Facades\DB::getQueryLog());
}

/**
 * 对象转数组
 */
if (!function_exists('objToArr')){
    function objToArr($obj)
    {
        return is_object($obj) ? json_decode(json_encode($obj), true) : $obj;
    }
}

/**
 * 是否网址
 * @param $v
 * @return bool
 */
if (!function_exists('isUrl')) {
    function isUrl($v)
    {
        $pattern = "#(http|https)://(.*\.)?.*\..*#i";
        if (preg_match($pattern, $v)) {
            return true;
        } else {
            return false;
        }
    }
}

/**与游服的http交互 */
function sendMsgToServer($dataArr){

    ksort($dataArr);

    $str = "";
    $data = [];
    foreach($dataArr as $key => $value){
            $str .= $key . $value;
            $data[] = $key."=".$value;
    }
    $str .= "1234567890987654321";

    $sign = md5($str);
    $data[] = "sign=".$sign;

    $p_str = implode('&', $data);

    $url = "http://127.0.0.1:3839/cgi-bin/admin?".$p_str;

    return file_get_contents($url);
}

function sendAliyunSms($code, $mobile){
    //测试的时候用，发送短信要钱的
    Redis::setex("SMS_CODE:".$mobile,300,$code);
    //return true;
    $TemplateCode = 'SMS_175544086';

    AlibabaCloud::accessKeyClient(env('ALIYUN_SMS_APPID'), env('ALIYUN_SMS_SCRECT'))
                ->regionId('cn-hangzhou')
                ->asDefaultClient();
    try {
        $result = AlibabaCloud::rpc()
            ->product('Dysmsapi')
            // ->scheme('https') // https | http
            ->version('2017-05-25')
            ->action('SendSms')
            ->method('POST')
            ->host('dysmsapi.aliyuncs.com')
            ->options([
                        'query' => [
                            'RegionId' => "cn-hangzhou",
                            'PhoneNumbers' => $mobile,
                            'SignName' => "Next66",
                            'TemplateCode' => $TemplateCode,
                            'TemplateParam' => "{\"code\":\"$code\"}",
                            ],
                        ])
            ->request();
        $result = $result->toArray();
        if($result['Code'] != "OK")
        {
            return $result['Message'];
        }
        Redis::setex("SMS_CODE:".$mobile,300,$code);
    } catch (ClientException $e) {
        return $e->getErrorMessage() . PHP_EOL;
    } catch (ServerException $e) {
        return $e->getErrorMessage() . PHP_EOL;
    }
    return true;
}